<script setup lang="ts">
import { onMounted, ref, getCurrentInstance, onUnmounted } from 'vue'
// 组件
import { ElMessage } from 'element-plus'
// 接口
import type { IMenuData, IMenuResponseData } from '@/api/system/menu/type'
import type { IMenuByRoleResponseData } from '@/api/divide/menu/type'
import type { IRoleData } from '@/api/system/role/type'
import type { ResponseData } from '@/types/common'
// api
import { reqMenuList } from '@/api/system/menu/index'
import { reqMenuByRole, reqMenuAssign } from '@/api/divide/menu/index'
// utils
import { treeToArray } from '@/utils/tree'

// 树元素
let treeRef = ref()
// 角色id
let roleId = ref<number>(0)
// 组件实例
let mainRef = ref()
// 列表数据
let treeData = ref<IMenuData[]>([])
// 列表高度
let treeHeight = ref<number>(0)
// 树形组件配置项
const props = {
  label: 'name',
  children: 'children',
}

// 获取菜单列表
const getList = async () => {
  const { code, data, message }: IMenuResponseData = await reqMenuList()
  if (code === 200) {
    treeData.value = data || []
  } else {
    ElMessage({
      type: 'error',
      message,
    })
  }
}
// 根据角色id获取菜单
const getMenuByRole = async (id: number) => {
  const { code, data }: IMenuByRoleResponseData = await reqMenuByRole(id)
  if (code === 200) {
    setTableChecked(data)
  }
}
// 计算列表高度
const countTableHeight = () => {
  treeHeight.value = mainRef?.value?.$el?.offsetHeight - 30 || 0
}
// 保存分配的角色
const handleSubmit = async () => {
  // 获取选中行
  const permissionIdList = treeRef.value.getCheckedKeys()
  if (!permissionIdList.length) return
  const { code, message }: ResponseData = await reqMenuAssign({
    roleId: roleId.value,
    permissionIdList,
  })
  ElMessage({
    type: code === 200 ? 'success' : 'error',
    message,
  })
  getList()
}
// 设置列表页选中
const setTableChecked = (list: IMenuData[]) => {
  if (!list.length) return
  // 勾选分配角色
  const checkedIds: IMenuData[] = treeToArray(list).map((item) => {
    return item.id
  })
  treeRef.value.setCheckedKeys(checkedIds)
}

// 组件通信
const emitter =
  getCurrentInstance()?.appContext.config.globalProperties.$emitter

// 订阅
emitter.on('divide_role_row_click', (row: IRoleData) => {
  roleId.value = row.id
  // 根据角色id获取菜单
  getMenuByRole(row.id)
})

onMounted(() => {
  getList()
  countTableHeight()
})
onUnmounted(() => {
  // 移除订阅
  emitter.off('divide_role_row_click')
})
</script>
<template>
  <el-container>
    <el-header>
      <el-form>
        <el-form-item>
          <el-button type="primary" @click="handleSubmit">保存</el-button>
        </el-form-item>
      </el-form>
    </el-header>
    <el-main ref="mainRef" class="menu-main">
      <el-tree
        ref="treeRef"
        :data="treeData"
        node-key="id"
        :props="props"
        show-checkbox
        default-expand-all
        highlight-current
        check-on-click-node
        :expand-on-click-node="false"
        :style="{ height: treeHeight }"
      />
    </el-main>
  </el-container>
</template>
